/******************************************************************************/
/*                                                                            */
/*  Copyright (c) 2009: ngi-central.org                                       */
/*  All rights reserved.                                                      */
/*                                                                            */
/******************************************************************************/


#include <boost/test/unit_test.hpp>

#include "..\..\include\sgl\polygon.h"

BOOST_AUTO_TEST_SUITE( polygon3d )


BOOST_AUTO_TEST_CASE( polygon3d__default_constructor )
{
	sgl::polygon<3> a;

	BOOST_CHECK( a.size() == 0 );

	sgl::polygon<3> b(
		sgl::quadrilateral<3>(
			sgl::point<3>(1, 2, 3),
			sgl::point<3>(4, 5, 6),
			sgl::point<3>(7, 8, 9),
			sgl::point<3>(10, 11, 12)));
	
	BOOST_CHECK( b[0][0] == 1 );
	BOOST_CHECK( b[0][1] == 2 );
	BOOST_CHECK( b[0][2] == 3 );
	BOOST_CHECK( b[1][0] == 4 );
	BOOST_CHECK( b[1][1] == 5 );
	BOOST_CHECK( b[1][2] == 6 );
	BOOST_CHECK( b[2][0] == 7 );
	BOOST_CHECK( b[2][1] == 8 );
	BOOST_CHECK( b[2][2] == 9 );
	BOOST_CHECK( b[3][0] == 10 );
	BOOST_CHECK( b[3][1] == 11 );
	BOOST_CHECK( b[3][2] == 12 );
}

BOOST_AUTO_TEST_CASE( polygon3d__copy_constructor )
{
	sgl::polygon<3> a(
		sgl::polygon<3>(
			sgl::quadrilateral<3>(
				sgl::point<3>(1, 2, 3),
				sgl::point<3>(4, 5, 6),
				sgl::point<3>(7, 8, 9),
				sgl::point<3>(10, 11, 12))));

	BOOST_CHECK( a[0][0] == 1 );
	BOOST_CHECK( a[0][1] == 2 );
	BOOST_CHECK( a[0][2] == 3 );
	BOOST_CHECK( a[1][0] == 4 );
	BOOST_CHECK( a[1][1] == 5 );
	BOOST_CHECK( a[1][2] == 6 );
	BOOST_CHECK( a[2][0] == 7 );
	BOOST_CHECK( a[2][1] == 8 );
	BOOST_CHECK( a[2][2] == 9 );
	BOOST_CHECK( a[3][0] == 10 );
	BOOST_CHECK( a[3][1] == 11 );
	BOOST_CHECK( a[3][2] == 12 );
}

BOOST_AUTO_TEST_CASE( polygon3d__copy_assignment )
{
	sgl::polygon<3> a;
	a = sgl::polygon<3>(
			sgl::quadrilateral<3>(
				sgl::point<3>(1, 2, 3),
				sgl::point<3>(4, 5, 6),
				sgl::point<3>(7, 8, 9),
				sgl::point<3>(10, 11, 12)));

	BOOST_CHECK( a[0][0] == 1 );
	BOOST_CHECK( a[0][1] == 2 );
	BOOST_CHECK( a[0][2] == 3 );
	BOOST_CHECK( a[1][0] == 4 );
	BOOST_CHECK( a[1][1] == 5 );
	BOOST_CHECK( a[1][2] == 6 );
	BOOST_CHECK( a[2][0] == 7 );
	BOOST_CHECK( a[2][1] == 8 );
	BOOST_CHECK( a[2][2] == 9 );
	BOOST_CHECK( a[3][0] == 10 );
	BOOST_CHECK( a[3][1] == 11 );
	BOOST_CHECK( a[3][2] == 12 );
}

BOOST_AUTO_TEST_CASE( polygon3d__swap )
{
	sgl::polygon<3> a(sgl::polygon<3>(
		sgl::quadrilateral<3>(
			sgl::point<3>(1, 2, 3),
			sgl::point<3>(4, 5, 6),
			sgl::point<3>(7, 8, 9),
			sgl::point<3>(10, 11, 12))));
	sgl::polygon<3> b;

	a.swap(b);

	BOOST_CHECK( a.size() == 0 );
	BOOST_CHECK( b[0][0] == 1 );
	BOOST_CHECK( b[0][1] == 2 );
	BOOST_CHECK( b[0][2] == 3 );
	BOOST_CHECK( b[1][0] == 4 );
	BOOST_CHECK( b[1][1] == 5 );
	BOOST_CHECK( b[1][2] == 6 );
	BOOST_CHECK( b[2][0] == 7 );
	BOOST_CHECK( b[2][1] == 8 );
	BOOST_CHECK( b[2][2] == 9 );
	BOOST_CHECK( b[3][0] == 10 );
	BOOST_CHECK( b[3][1] == 11 );
	BOOST_CHECK( b[3][2] == 12 );

	b.swap(a);

	BOOST_CHECK( a[0][0] == 1 );
	BOOST_CHECK( a[0][1] == 2 );
	BOOST_CHECK( a[0][2] == 3 );
	BOOST_CHECK( a[1][0] == 4 );
	BOOST_CHECK( a[1][1] == 5 );
	BOOST_CHECK( a[1][2] == 6 );
	BOOST_CHECK( a[2][0] == 7 );
	BOOST_CHECK( a[2][1] == 8 );
	BOOST_CHECK( a[2][2] == 9 );
	BOOST_CHECK( a[3][0] == 10 );
	BOOST_CHECK( a[3][1] == 11 );
	BOOST_CHECK( a[3][2] == 12 );
	BOOST_CHECK( b.size() == 0 );
}

BOOST_AUTO_TEST_CASE( polygon3d__geometric_type )
{
	sgl::polygon<3> a;

	BOOST_CHECK( a.type() == sgl::geometric_primitive<>::polygon );
}

BOOST_AUTO_TEST_CASE( polygon3d__dimensions )
{
	sgl::polygon<3> a;

	BOOST_CHECK( a.dimensions() == 3 );
}

BOOST_AUTO_TEST_CASE( polygon3d__operator_equality )
{
	sgl::polygon<3> a;
	sgl::polygon<3> b;

	BOOST_CHECK( a == b );

	sgl::polygon<3> c(
		sgl::quadrilateral<3>(
			sgl::point<3>(1, 2, 3), sgl::point<3>(4, 5, 6), 
			sgl::point<3>(7, 8, 9), sgl::point<3>(7, 8, 9)));
	sgl::polygon<3> d(
		sgl::quadrilateral<3>(
			sgl::point<3>(1, 2, 3), sgl::point<3>(4, 5, 6), 
			sgl::point<3>(7, 8, 9), sgl::point<3>(7, 8, 9)));

	BOOST_CHECK( c == d );
}

BOOST_AUTO_TEST_CASE( polygon3d__operator_inequality )
{
	sgl::polygon<3> a;
	sgl::polygon<3> b(
		sgl::quadrilateral<3>(
			sgl::point<3>(1, 2, 3), sgl::point<3>(4, 5, 6), 
			sgl::point<3>(7, 8, 9), sgl::point<3>(7, 8, 9)));

	BOOST_CHECK( a != b );
}

BOOST_AUTO_TEST_CASE( polygon3d__addition )
{
	sgl::polygon<3> a(sgl::polygon<3>(
		sgl::quadrilateral<3>(
			sgl::point<3>(0, 0, 0), sgl::point<3>(0, 0, 0),
			sgl::point<3>(0, 0, 0), sgl::point<3>(0, 0, 0))));
	a += sgl::vector<3>(1, 2, 3);

	BOOST_CHECK( a[0][0] == 1 );
	BOOST_CHECK( a[0][1] == 2 );
	BOOST_CHECK( a[0][2] == 3 );
	BOOST_CHECK( a[1][0] == 1 );
	BOOST_CHECK( a[1][1] == 2 );
	BOOST_CHECK( a[1][2] == 3 );
	BOOST_CHECK( a[2][0] == 1 );
	BOOST_CHECK( a[2][1] == 2 );
	BOOST_CHECK( a[2][2] == 3 );
	BOOST_CHECK( a[3][0] == 1 );
	BOOST_CHECK( a[3][1] == 2 );
	BOOST_CHECK( a[3][2] == 3 );

	sgl::polygon<3> b(
		sgl::quadrilateral<3>(
			sgl::point<3>(0, 0, 0), sgl::point<3>(0, 0, 0), 
			sgl::point<3>(0, 0, 0), sgl::point<3>(0, 0, 0)));
	sgl::vector<3> c(1, 2, 3);
	sgl::polygon<3> d = b+c;

	BOOST_CHECK( d[0][0] == 1 );
	BOOST_CHECK( d[0][1] == 2 );
	BOOST_CHECK( d[0][2] == 3 );
	BOOST_CHECK( d[1][0] == 1 );
	BOOST_CHECK( d[1][1] == 2 );
	BOOST_CHECK( d[1][2] == 3 );
	BOOST_CHECK( d[2][0] == 1 );
	BOOST_CHECK( d[2][1] == 2 );
	BOOST_CHECK( d[2][2] == 3 );
	BOOST_CHECK( d[3][0] == 1 );
	BOOST_CHECK( d[3][1] == 2 );
	BOOST_CHECK( d[3][2] == 3 );

	sgl::polygon<3> e = c+b;

	BOOST_CHECK( e[0][0] == 1 );
	BOOST_CHECK( e[0][1] == 2 );
	BOOST_CHECK( e[0][2] == 3 );
	BOOST_CHECK( e[1][0] == 1 );
	BOOST_CHECK( e[1][1] == 2 );
	BOOST_CHECK( e[1][2] == 3 );
	BOOST_CHECK( e[2][0] == 1 );
	BOOST_CHECK( e[2][1] == 2 );
	BOOST_CHECK( e[2][2] == 3 );
	BOOST_CHECK( e[3][0] == 1 );
	BOOST_CHECK( e[3][1] == 2 );
	BOOST_CHECK( e[3][2] == 3 );
}

BOOST_AUTO_TEST_CASE( polygon3d__subtraction )
{
	sgl::polygon<3> a(sgl::polygon<3>(
		sgl::quadrilateral<3>(
			sgl::point<3>(0, 0, 0), sgl::point<3>(0, 0, 0),
			sgl::point<3>(0, 0, 0), sgl::point<3>(0, 0, 0))));
	a -= sgl::vector<3>(1, 2, 3);

	BOOST_CHECK( a[0][0] == -1 );
	BOOST_CHECK( a[0][1] == -2 );
	BOOST_CHECK( a[0][2] == -3 );
	BOOST_CHECK( a[1][0] == -1 );
	BOOST_CHECK( a[1][1] == -2 );
	BOOST_CHECK( a[1][2] == -3 );
	BOOST_CHECK( a[2][0] == -1 );
	BOOST_CHECK( a[2][1] == -2 );
	BOOST_CHECK( a[2][2] == -3 );
	BOOST_CHECK( a[3][0] == -1 );
	BOOST_CHECK( a[3][1] == -2 );
	BOOST_CHECK( a[3][2] == -3 );

	sgl::polygon<3> b(
		sgl::quadrilateral<3>(
			sgl::point<3>(0, 0, 0), sgl::point<3>(0, 0, 0), 
			sgl::point<3>(0, 0, 0), sgl::point<3>(0, 0, 0)));
	sgl::vector<3> c(1, 2, 3);
	sgl::polygon<3> d = b-c;

	BOOST_CHECK( d[0][0] == -1 );
	BOOST_CHECK( d[0][1] == -2 );
	BOOST_CHECK( d[0][2] == -3 );
	BOOST_CHECK( d[1][0] == -1 );
	BOOST_CHECK( d[1][1] == -2 );
	BOOST_CHECK( d[1][2] == -3 );
	BOOST_CHECK( d[2][0] == -1 );
	BOOST_CHECK( d[2][1] == -2 );
	BOOST_CHECK( d[2][2] == -3 );
	BOOST_CHECK( d[3][0] == -1 );
	BOOST_CHECK( d[3][1] == -2 );
	BOOST_CHECK( d[3][2] == -3 );
}

BOOST_AUTO_TEST_SUITE_END()

